<template>
  <div>
    <div>hello life cycle {{ msg }}</div>
    <button class="btn" @click="btnClick">修改msg</button>
  </div>
</template>

<script lang="ts" setup>
/**
 * 生命周期钩子 
 * setup 执行时，生命周期钩子不会立即执行，而是等到组件渲染完成之后才会执行。
 * 生命周期钩子的执行顺序：
 * onBeforeCreate -> onCreated -> onBeforeMount -> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted
 * error: onBeforeCreate -> onCreated -> onBeforeMount -> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted -> error
 * 注意：不要在 setup 中使用箭头函数，因为箭头函数没有 this 指向，导致无法正确执行生命周期钩子。
 * 注意：不要在 setup 中使用异步函数，因为异步函数会导致组件渲染完成之后才执行生命周期钩子，导致一些问题。
 * 注意：不要在 setup 中使用 return 返回 JSX 元素，因为 setup 只能返回纯对象，不能返回 JSX 元素。
 * 注意：不要在 setup 中使用 ref，因为 ref 只能在 setup 中使用。
 * 注意：不要在 setup 中使用 render 函数，因为 render 函数只能在 setup 中使用。
 * 注意：不要在 setup 中使用 import 导入其他模块，因为 import 语句只能在 setup 中使用。
 * 注意：不要在 setup 中使用 export default，因为 export default 只能在 setup 中使用。
 * 注意：不要在 setup 中使用 export，因为 export 只能在 setup 中使用。
 * 注意：不要在 setup 中使用 JSX，因为 JSX 不能在 setup 中使用。
 * 注意：不要在生命周期钩子中使用箭头函数，因为箭头函数没有 this 指向，导致无法正确执行生命周期钩子。
 * 注意：不要在生命周期钩子中使用异步函数，因为异步函数会导致组件渲染完成之后才执行生命周期钩子，导致一些问题。
 * 注意：不要在生命周期钩子中使用 return 返回 JSX 元素，因为生命周期钩子只能返回纯对象，不能返回 JSX 元素。 
 * 
 * 生命周期钩子的作用：
 * onBeforeCreate：组件实例被创建，数据观测(data observer)和事件侦听器(event listener)都未被创建。
 * onCreated：组件实例创建完成，但挂载还未开始。
 * onBeforeMount：组件实例被挂载，但DOM还未渲染。
 * onMounted：组件实例挂载完成，DOM渲染完成。
 * onBeforeUpdate：组件实例更新之前。
 * onUpdated：组件实例更新之后。
 * onBeforeUnmount：组件实例销毁之前。
 * onUnmounted：组件实例销毁之后。
 * error：组件渲染过程中出现错误。
 * 
 * 生命周期钩子的特点：
 * 1. 生命周期钩子在组件实例化时，只执行一次。
 * 2. 生命周期钩子在组件实例化之后，执行顺序是先父后子。
 * 
 * 生命周期钩子的注意事项： 
 * 1. 生命周期钩子不能使用箭头函数，因为箭头函数没有 this 指向，导致无法正确执行生命周期钩子。
 * 2. 生命周期钩子不能使用异步函数，因为异步函数会导致组件渲染完成之后才执行生命周期钩子，导致一些问题。
 * 3. 生命周期钩子不能使用 return 返回 JSX 元素，因为生命周期钩子只能返回纯对象，不能返回 JSX 元素。 
 * 4. 生命周期钩子不能使用 ref，因为 ref 只能在 setup 中使用。
 * 5. 生命周期钩子不能使用 render 函数，因为 render 函数只能在 setup 中使用。
 * 6. 生命周期钩子不能使用 import 导入其他模块，因为 import 语句只能在 setup 中使用。
 * 7. 生命周期钩子不能使用 export default，因为 export default 只能在 setup 中使用。
 * 8. 生命周期钩子不能使用 export，因为 export 只能在 setup 中使用。
 * 9. 生命周期钩子不能使用 JSX，因为 JSX 不能在 setup 中使用。
 * 
 * 生命周期钩子的使用场景：
 * 1. 在组件实例创建之前，进行一些初始化操作。
 * 2. 在组件实例创建之后，进行一些操作，比如请求数据,渲染DOM,绑定事件,清除定时器等
 * 3. 组件渲染过程中出现错误，进行一些错误处理。
 * 
 * setupe 生命周期钩子：  
 * onBeforeMount -> onMounted -> onBeforeUpdate -> onUpdated -> onBeforeUnmount -> onUnmounted
 * 没有 onBeforeCreate， onCreated这个两个钩子，setup就是这两个钩子的集合。
 * 
*/
import { onBeforeMount, onBeforeUnmount, onBeforeUpdate, onMounted, onUnmounted, onUpdated, ref } from 'vue';
const msg = ref("")
const btnClick = () => {
  msg.value = msg.value + "~"
}
console.log("--------------setup执行了");

//初始化data完成
onBeforeMount(() => {
  console.log("onBeforeMount");

})
//初始化data（代理）后，挂载
onMounted(() => {
  console.log("--------------onMounted");
})

//更新状态（data）之后，但是dom还没有完成更新
onBeforeUpdate(() => {
  console.log("onBeforeUpdate");
})
onUpdated(() => {
  console.log("--------------onUpdated");
})

//卸载之前，当这个钩子被调用时，组件实例依然还保有全部的功能。
onBeforeUnmount(() => {
  console.log("onBeforeUnmount");
})
onUnmounted(() => {
  console.log("--------------onUnmounted");
})
//错误处理
// errorCaptured(() => {
//   console.log("--------------errorCaptured");
// })

</script>

<style scoped lang='scss'></style>
